package smartgrid.agents.prosumer.ds;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import smartgrid.agents.prosumer.IProsumerAgent;
import smartgrid.agents.prosumer.ProsumerAbstractAgent;
import smartgrid.conf.ProsumerConf;
import smartgrid.modules.normative.norm.Norm;
import smartgrid.modules.normative.salience.NormSalience;
import smartgrid.modules.normative.salience.NormSalience.Status;
import smartgrid.modules.normative.sanction.InformationSanction;
import smartgrid.modules.normative.sanction.PunishmentInformationSanction;
import smartgrid.modules.normative.sanction.PunishmentSanction;
import smartgrid.modules.normative.sanction.SanctionAbstract;
import smartgrid.modules.trade.Contract;
import smartgrid.modules.trade.Demand;
import smartgrid.modules.trade.Offer;
import smartgrid.output.AbstractEntity;
import smartgrid.output.ContractOutputEntity;
import smartgrid.output.ProsumerDSOutputEntity;
import smartgrid.output.ProsumerDSOutputEntity.Field;
import smartgrid.output.OutputController;
import smartgrid.output.AbstractEntity.EntityType;
import smartgrid.util.random.RandomUtil;
import smartgrid.util.sort.Sort;

/**
 * Implements a Prosumer using the sanctioning strategy described in the paper
 * 
 * Dynamic Sanctioning for Robust and Cost-Efficient Norm Compliance
 * Daniel Villatoro, Giulia Andrighetto, Jordi Sabater-Mir, Rosaria Conte
 * IJCAI/AAAI, 414-419, 2011
 * 
 */
public class ProsumerDSAgent extends ProsumerAbstractAgent {
	
	private static final Logger	logger	= LoggerFactory
																					.getLogger(ProsumerDSAgent.class);
	
	private double							PUNISHMENT;
	
	private double							COST_PUNISH;
	
	private double							DELTA_PUNISHMENT;
	
	private int									NORM_ACTIVATE_NUM_MSG;
	
	private int									NORM_ACTIVATE_NUM_ACTION;
	
	private double							NORM_ACTIVATE_SAL_THRESHOLD;
	
	private int									TOLERANCE_TO_VIOLATION;
	
	private double							INDIVIDUAL_WEIGHT;
	
	private double							NORMATIVE_WEIGHT;
	
	private NormSalience				normSalience;
	
	private int									normativeMsg;
	
	private int									normativeAction;
	
	private int									priorViolators;
	
	private double							totalSanctions;
	
	private double							sanctionCost;
	
	private int[][]							sanctioning;
	
	
	public ProsumerDSAgent(Integer id, ProsumerConf conf, String prosumerFilename) {
		super(id, conf);
		
		this.PUNISHMENT = conf.getProsumerDSConf().getPunishment();
		this.COST_PUNISH = conf.getProsumerDSConf().getCostToPunish();
		this.DELTA_PUNISHMENT = conf.getProsumerDSConf().getDeltaPunishment();
		this.NORM_ACTIVATE_NUM_MSG = conf.getProsumerDSConf()
				.getNormActivateNumMsg();
		this.NORM_ACTIVATE_NUM_ACTION = conf.getProsumerDSConf()
				.getNormActivateNumAction();
		this.NORM_ACTIVATE_SAL_THRESHOLD = conf.getProsumerDSConf()
				.getNormActivateSalThreshold();
		this.TOLERANCE_TO_VIOLATION = conf.getProsumerDSConf()
				.getToleranceToViolation();
		this.INDIVIDUAL_WEIGHT = conf.getProsumerDSConf().getIndividualWeight();
		this.NORMATIVE_WEIGHT = conf.getProsumerDSConf().getNormativeWeight();
		
		this.normSalience = new NormSalience(conf.getProsumerDSConf()
				.getNormSalience());
		
		if (conf.getProsumerDSConf().getNormActive()) {
			this.normSalience.setStatus(Status.ACTIVE);
		} else {
			this.normSalience.setStatus(Status.INACTIVE);
		}
		
		this.normativeMsg = 0;
		this.normativeAction = 0;
		this.priorViolators = 0;
		
		// Sanction per timestep
		this.sanctioning = new int[SanctionAbstract.Enforcer.values().length][SanctionAbstract.Type
				.values().length];
		for(int i = 0; i < this.sanctioning.length; i++) {
			for(int j = 0; j < this.sanctioning[i].length; j++) {
				this.sanctioning[i][j] = 0;
			}
		}
		this.totalSanctions = 0.0;
		this.sanctionCost = 0.0;
		
		OutputController.init(EntityType.DS_PROSUMER, prosumerFilename);
	}
	
	
	@Override
	public void initSim() {
		this.normSalience.setNumNeighbors(this.neighbors.get(this.id).size());
	}
	
	
	@Override
	public void initTimestep(int timestep) {
		super.initTimestep(timestep);
		
		for(int i = 0; i < this.sanctioning.length; i++) {
			for(int j = 0; j < this.sanctioning[i].length; j++) {
				this.sanctioning[i][j] = 0;
			}
		}
		
		this.totalSanctions = 0.0;
		this.sanctionCost = 0.0;
	}
	
	
	@Override
	public Offer getOffer() {
		if (this.hasExcessEnergyEstimation()) {
			
			double strategy = this.selfInterest;
			if (this.normSalience.isActive()) {
				strategy = (this.INDIVIDUAL_WEIGHT * strategy)
						+ (this.NORMATIVE_WEIGHT * (1 - this.normSalience.getSalience()));
			}
			
			double minEstimate = (this.generateEstimation * this.generateAccuracy)
					- (this.consumeEstimation * (1 + (1 - this.consumeAccuracy)));
			
			double maxEstimate = (this.generateEstimation * (1 + (1 - this.generateAccuracy)))
					- (this.consumeEstimation * this.consumeAccuracy);
			
			double offering = Math.max(0, minEstimate
					+ ((maxEstimate - minEstimate) * strategy));
			
			this.offer = new Offer(this.id, offering, this.sellingPrice,
					new ArrayList<Integer>());
			
			logger.debug("[ID=" + this.id + "] [SELF-INTEREST=" + this.selfInterest
					+ "] [NORM-SALIENCE=" + this.normSalience.getSalience()
					+ "] [GENERATE ESTIMATION=" + this.generateEstimation + " ACCURACY="
					+ this.generateAccuracy + "] [CONSUME ESTIMATION="
					+ this.consumeEstimation + " ACCURACY=" + this.consumeAccuracy
					+ "] [MIN_ESTIMATE=" + minEstimate + "] [MAX_ESTIMATE=" + maxEstimate
					+ "] [OFFERING=" + offering + "]");
			
		}
		
		return this.offer;
	}
	
	
	@Override
	public Demand getDemand(Map<Integer, Offer> offers) {
		if (!this.hasExcessEnergyEstimation()) {
			
			double neededEnergy = this.consumeEstimation - this.generateEstimation;
			
			// Calculate the farthest Prosumer
			Map<Integer, Double> prosumerDists = new HashMap<Integer, Double>();
			double maxHops = 0;
			for(Integer offerId : offers.keySet()) {
				Offer offer = offers.get(offerId);
				int prosumerId = offer.getProsumer();
				
				if (offer.getQuantity() >= neededEnergy) {
					
					double prosumerDist = -1;
					Map<Integer, Double> distances = this.distances.get(this.id);
					if (distances.containsKey(prosumerId)) {
						prosumerDist = distances.get(prosumerId);
						if (maxHops < prosumerDist) {
							maxHops = prosumerDist;
						}
					}
					prosumerDists.put(prosumerId, prosumerDist);
				}
			}
			
			Map<Integer, Double> unsortedOffers = new TreeMap<Integer, Double>();
			for(Integer prosumerId : prosumerDists.keySet()) {
				double prosumerDist = prosumerDists.get(prosumerId);
				if (prosumerDist != -1) {
					unsortedOffers.put(prosumerId,
							((double) prosumerDist / (double) maxHops));
				} else {
					unsortedOffers.put(prosumerId, 1.0);
				}
			}
			
			Queue<Integer> prefOffers = new LinkedList<Integer>();
			for(Entry<Integer, Double> entry : Sort
					.entriesSortedByValues(unsortedOffers)) {
				prefOffers.add(entry.getKey());
			}
			
			this.demand = new Demand(this.id, neededEnergy, prefOffers);
		}
		
		return this.demand;
	}
	
	
	@Override
	public void evaluateContract() {
		if (this.contract != null) {
			if (Norm.evaluateContract(this.contract).equals(Norm.Status.COMPLIED)) {
				this.contract.setComplied(true);
			} else {
				this.contract.setComplied(false);
			}
		}
	}
	
	
	@Override
	public List<SanctionAbstract> decideSanction() {
		List<SanctionAbstract> sanctions = new ArrayList<SanctionAbstract>();
		
		if ((this.contract != null) && (this.contract.getBuyer() == this.id)
				&& (!this.contract.getComplied())) {
			
			if (this.normSalience.isActive()) {
				double sanctionProb = this.normSalience.getSalience();
				
				// Send a Sanction
				if (RandomUtil.nextDouble() < sanctionProb) {
					sanctions.add(new PunishmentInformationSanction(this.id,
							this.contract.getSupplier(), this.PUNISHMENT));
					
					this.sanctionCost += this.COST_PUNISH;
					this.wealth -= this.COST_PUNISH;
					
					this.sanctioning[SanctionAbstract.Enforcer.APPLIED.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
							.ordinal()]++;
					
					// Send a Normative Information
				} else {
					sanctions.add(new InformationSanction(this.id, this.contract
							.getSupplier()));
					
					this.sanctioning[SanctionAbstract.Enforcer.APPLIED.ordinal()][SanctionAbstract.Type.INFORMATION
							.ordinal()]++;
				}
				
			} else {
				
				// Calculate the number of Violators and Compliers
				int complied = 0;
				int violated = 0;
				for(IProsumerAgent neighbor : this.neighbors.get(this.id)) {
					if (neighbor.getContract() != null) {
						if (neighbor.getContract().getComplied()) {
							complied++;
						} else {
							violated++;
						}
					}
				}
				
				double punishProb = 0;
				if ((complied + violated) > 0) {
					punishProb = (double) complied
							/ ((double) complied + (double) violated);
				}
				
				// Send a Punishment
				if (RandomUtil.nextDouble() < punishProb) {
					sanctions.add(new PunishmentSanction(this.id, this.contract
							.getSupplier(), this.PUNISHMENT));
					
					this.sanctionCost += this.COST_PUNISH;
					this.wealth -= this.COST_PUNISH;
					
					this.sanctioning[SanctionAbstract.Enforcer.APPLIED.ordinal()][SanctionAbstract.Type.PUNISHMENT
							.ordinal()]++;
				}
			}
		}
		
		return sanctions;
	}
	
	
	@Override
	public void handleSanction(SanctionAbstract sanction) {
		
		double value = 0.0;
		if (sanction instanceof PunishmentSanction) {
			value = ((PunishmentSanction) sanction).getPunishment();
			
		} else if (sanction instanceof PunishmentInformationSanction) {
			value = ((PunishmentInformationSanction) sanction).getPunishment();
			
		} else if (sanction instanceof InformationSanction) {
			
		}
		this.totalSanctions += value;
		this.wealth -= value;
	}
	
	
	@Override
	public void updateStrategy(
			Map<Integer, List<SanctionAbstract>> sanctionsSender,
			Map<Integer, List<SanctionAbstract>> sanctionsReceiver) {
		
		int own = 0;
		int complied = 0;
		int violated = 0;
		int npv = 0;
		if (this.contract != null) {
			
			if (this.contract.getSupplier() == this.id) {
				
				if (this.contract.getComplied()) {
					own = 1;
					
				} else {
					own = -1;
					
					List<SanctionAbstract> sanctionList = sanctionsReceiver.get(this.id);
					
					if ((sanctionList != null) && (!sanctionList.isEmpty())) {
						
						for(SanctionAbstract sanction : sanctionList) {
							
							if (sanction instanceof PunishmentSanction) {
								this.sanctioning[SanctionAbstract.Enforcer.RECEIVED.ordinal()][SanctionAbstract.Type.PUNISHMENT
										.ordinal()]++;
								this.normativeAction++;
								
							} else if (sanction instanceof PunishmentInformationSanction) {
								this.sanctioning[SanctionAbstract.Enforcer.RECEIVED.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
										.ordinal()]++;
								this.normativeAction++;
								this.normativeMsg++;
								
							} else if (sanction instanceof InformationSanction) {
								this.sanctioning[SanctionAbstract.Enforcer.RECEIVED.ordinal()][SanctionAbstract.Type.INFORMATION
										.ordinal()]++;
								this.normativeMsg++;
							}
						}
						
					} else {
						npv++;
					}
				}
				
				// Agent is the Buyer
			} else if (this.contract.getBuyer() == this.id) {
				own = 0;
				if (this.contract.getComplied()) {
					complied++;
					this.normativeAction++;
				} else {
					violated++;
				}
			}
		}
		
		List<Integer> analyzedContracts = new ArrayList<Integer>();
		Map<Integer, List<Integer>> exclude = new HashMap<Integer, List<Integer>>();
		
		for(IProsumerAgent neighbor : this.neighbors.get(this.id)) {
			Contract contract = neighbor.getContract();
			int neighborId = neighbor.getId();
			
			if ((contract != null) && (contract.getSupplier() != this.id)
					&& (contract.getBuyer() != this.id)
					&& (contract.getSupplier() == neighborId)
					&& (!analyzedContracts.contains(contract.getId()))) {
				
				if (contract.getComplied()) {
					complied++;
					this.normativeAction++;
					
				} else {
					
					violated++;
					
					// Calculate the received Sanctions
					if (sanctionsReceiver.containsKey(neighborId)) {
						
						for(SanctionAbstract sanction : sanctionsReceiver.get(neighborId)) {
							
							List<Integer> excluded;
							if (exclude.containsKey(sanction.getReceiver())) {
								excluded = exclude.get(sanction.getReceiver());
							} else {
								excluded = new ArrayList<Integer>();
							}
							
							if (!excluded.contains(sanction.getSender())) {
								excluded.add(sanction.getSender());
								exclude.put(sanction.getReceiver(), excluded);
								
								if (sanction instanceof PunishmentSanction) {
									this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.PUNISHMENT
											.ordinal()]++;
									this.normativeAction++;
									
								} else if (sanction instanceof PunishmentInformationSanction) {
									this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
											.ordinal()]++;
									this.normativeAction++;
									this.normativeMsg++;
									
								} else if (sanction instanceof InformationSanction) {
									this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.INFORMATION
											.ordinal()]++;
									this.normativeMsg++;
								}
							}
						}
						
					} else {
						npv++;
					}
					
					// Calculate the sent Sanctions
					if (sanctionsSender.containsKey(neighborId)) {
						
						for(SanctionAbstract sanction : sanctionsSender.get(neighborId)) {
							
							List<Integer> excluded;
							if (exclude.containsKey(sanction.getReceiver())) {
								excluded = exclude.get(sanction.getReceiver());
							} else {
								excluded = new ArrayList<Integer>();
							}
							
							if (!excluded.contains(sanction.getSender())) {
								excluded.add(sanction.getSender());
								exclude.put(sanction.getReceiver(), excluded);
								
								if (sanction instanceof PunishmentSanction) {
									this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.PUNISHMENT
											.ordinal()]++;
									this.normativeAction++;
									
								} else if (sanction instanceof PunishmentInformationSanction) {
									this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
											.ordinal()]++;
									this.normativeAction++;
									this.normativeMsg++;
									
								} else if (sanction instanceof InformationSanction) {
									this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.INFORMATION
											.ordinal()]++;
									this.normativeMsg++;
								}
							}
						}
					}
				}
				
				analyzedContracts.add(contract.getId());
			}
		}
		
		int pun = 0;
		for(SanctionAbstract.Enforcer enforcer : SanctionAbstract.Enforcer.values()) {
			pun += this.sanctioning[enforcer.ordinal()][SanctionAbstract.Type.PUNISHMENT
					.ordinal()];
		}
		
		int sanc = 0;
		for(SanctionAbstract.Enforcer enforcer : SanctionAbstract.Enforcer.values()) {
			sanc += this.sanctioning[enforcer.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
					.ordinal()];
		}
		
		int invoke = 0;
		for(SanctionAbstract.Enforcer enforcer : SanctionAbstract.Enforcer.values()) {
			invoke += this.sanctioning[enforcer.ordinal()][SanctionAbstract.Type.INFORMATION
					.ordinal()];
		}
		
		this.normSalience.updateSalience(own, complied, violated, npv, pun, sanc,
				invoke);
		
		// Update Self-Interest
		if ((this.contract != null) && (this.contract.getSupplier() == this.id)
				&& (own != 0)) {
			double offered = this.contract.getQtyOffered() * this.sellingPrice;
			double demanded = this.contract.getQtyDemanded() * this.sellingPrice;
			double supplied = this.contract.getQtySupplied() * this.sellingPrice;
			double consumed = this.contract.getQtyConsumed() * this.sellingPrice;
			double actual = Math.max(0, (this.generateReal - this.consumeReal))
					* this.sellingPrice;
			
			if (this.contract.getComplied()) {
				if (actual != 0) {
					this.selfInterest += (actual - consumed) / actual;
				}
			} else {
				if ((offered + this.totalSanctions) != 0) {
					this.selfInterest += (supplied - demanded - this.totalSanctions)
							/ (demanded + this.totalSanctions);
				}
			}
			
			this.selfInterest = Math.max(0.0, Math.min(1.0, this.selfInterest));
		}
		
		// Norm Adoption
		if ((!this.normSalience.isActive())
				&& (this.normSalience.getSalience() >= this.NORM_ACTIVATE_SAL_THRESHOLD)
				&& (this.normativeMsg >= this.NORM_ACTIVATE_NUM_MSG)
				&& (this.normativeAction >= this.NORM_ACTIVATE_NUM_ACTION)) {
			this.normSalience.setStatus(Status.ACTIVE);
		}
		
		if ((this.normSalience.isActive())
				&& (this.normSalience.getSalience() < this.NORM_ACTIVATE_SAL_THRESHOLD)) {
			this.normativeMsg = 0;
			this.normativeAction = 0;
			this.normSalience.setStatus(Status.INACTIVE);
		}
		
		// Dynamic Adaption Heuristic
		if ((this.priorViolators <= violated) && (violated > 0)
				&& (violated > this.TOLERANCE_TO_VIOLATION)) {
			this.PUNISHMENT += this.DELTA_PUNISHMENT;
		} else if ((this.priorViolators > violated)
				|| (violated < this.TOLERANCE_TO_VIOLATION)) {
			this.PUNISHMENT -= this.DELTA_PUNISHMENT;
		}
		
		this.priorViolators = violated;
		
		logger.info(this.timestep + " [AGENT " + this.id + "] " + this.selfInterest
				+ " " + this.normSalience.getSalience());
	}
	
	
	@Override
	public void generateOutput() {
		AbstractEntity entity = (ProsumerDSOutputEntity) OutputController
				.getEntity(EntityType.DS_PROSUMER);
		
		entity.setValue(Field.CYCLE.name(), this.timestep);
		entity.setValue(Field.PROSUMER_ID.name(), this.id);
		entity.setValue(Field.WEALTH.name(), this.wealth);
		entity.setValue(Field.SELF_INTEREST.name(), this.selfInterest);
		entity.setValue(Field.NORM_STATUS.name(), this.normSalience.getStatus()
				.name());
		entity.setValue(Field.NORM_SALIENCE.name(), normSalience.getSalience());
		entity.setValue(Field.CONSUME_ESTIMATION.name(), this.consumeEstimation);
		entity.setValue(Field.GENERATE_ESTIMATION.name(), this.generateEstimation);
		entity.setValue(Field.CONSUME_REAL.name(), this.consumeReal);
		entity.setValue(Field.GENERATE_REAL.name(), this.generateReal);
		entity.setValue(Field.CONSUME_ACCURACY.name(), this.consumeAccuracy);
		entity.setValue(Field.GENERATE_ACCURACY.name(), this.generateAccuracy);
		
		if (this.contract != null) {
			
			AbstractEntity contractEntity = (ContractOutputEntity) OutputController
					.getEntity(EntityType.CONTRACT, this.contract.getId());
			
			contractEntity.setValue(
					ContractOutputEntity.Field.SELLER_COMPLIED.name(),
					this.contract.getComplied());
			
			contractEntity.setActive();
			
			OutputController.setEntity(EntityType.CONTRACT, contractEntity);
			
			// Supplier
			if (this.contract.getSupplier() == this.id) {
				entity.setValue(Field.SUPPLIER.name(), true);
				entity.setValue(Field.BUYER.name(), false);
				entity.setValue(Field.BALANCE.name(), this.energyBalance());
				
				// Buyer
			} else if (this.contract.getBuyer() == this.id) {
				entity.setValue(Field.SUPPLIER.name(), false);
				entity.setValue(Field.BUYER.name(), true);
				entity.setValue(Field.BALANCE.name(), this.energyBalance());
			}
			
		} else {
			entity.setValue(Field.SUPPLIER.name(), false);
			entity.setValue(Field.BUYER.name(), false);
			entity.setValue(Field.BALANCE.name(), 0.0);
		}
		
		entity.setValue(Field.PROVIDER_BUY.name(), this.providerBuyEnergy);
		entity.setValue(Field.PROVIDER_PAID.name(), this.providerAmountPaid);
		entity.setValue(Field.PROVIDER_SELL.name(), this.providerSellEnergy);
		entity
				.setValue(Field.PROVIDER_RECEIVED.name(), this.providerAmountReceived);
		entity.setValue(Field.SANCTIONING_COST.name(), this.sanctionCost);
		
		entity
				.setValue(
						Field.A_PUN_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.APPLIED.ordinal()][SanctionAbstract.Type.PUNISHMENT
								.ordinal()]);
		
		entity
				.setValue(
						Field.A_PUN_INFO_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.APPLIED.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
								.ordinal()]);
		
		entity
				.setValue(
						Field.A_INFO_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.APPLIED.ordinal()][SanctionAbstract.Type.INFORMATION
								.ordinal()]);
		
		entity
				.setValue(
						Field.R_PUN_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.RECEIVED.ordinal()][SanctionAbstract.Type.PUNISHMENT
								.ordinal()]);
		
		entity
				.setValue(
						Field.R_PUN_INFO_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.RECEIVED.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
								.ordinal()]);
		
		entity
				.setValue(
						Field.R_INFO_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.RECEIVED.ordinal()][SanctionAbstract.Type.INFORMATION
								.ordinal()]);
		
		entity
				.setValue(
						Field.O_PUN_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.PUNISHMENT
								.ordinal()]);
		
		entity
				.setValue(
						Field.O_PUN_INFO_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.PUNISHMENT_INFORMATION
								.ordinal()]);
		
		entity
				.setValue(
						Field.O_INFO_SANCTION.name(),
						this.sanctioning[SanctionAbstract.Enforcer.OBSERVED.ordinal()][SanctionAbstract.Type.INFORMATION
								.ordinal()]);
		
		entity.setActive();
		
		OutputController.setEntity(EntityType.DS_PROSUMER, entity);
	}
}